﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using BloggerAutoPoster.Common.Toolkit;
using BloggerAutoPoster.Infrastructure.Models;
using BloggerAutoPoster.Common.Mvvm;

namespace BloggerAutoPoster.Infrastructure.ViewModels
{
    public class AlertConfirmBoxViewModel : INotifyPropertyChanged
    {
        #region Fields (3)

        AlertConfirmBoxModel _alertConfirmBoxModel;
        readonly List<AlertConfirmBoxModel> _localCache;
        string _saveFilePath;

        #endregion Fields

        #region Constructors (1)

        public AlertConfirmBoxViewModel()
        {
            _localCache = new List<AlertConfirmBoxModel>();
            setupMessengers();
            AlertConfirmBoxModel = new AlertConfirmBoxModel
            {
                IsVisible = Visibility.Collapsed,
                ShowConfirm = Visibility.Collapsed,
                ShowCancel = Visibility.Collapsed,
                CurrentState = "Normal"
            };
            setupCommands();
        }

        #endregion Constructors

        #region Properties (6)

        public AlertConfirmBoxModel AlertConfirmBoxModel
        {
            set
            {
                _alertConfirmBoxModel = value;
                notifyPropertyChanged("AlertConfirmBoxModel");
            }
            get { return _alertConfirmBoxModel; }
        }

        public DelegateCommand<object> CancelCommand { set; get; }

        public DelegateCommand<object> ConfirmCommand { set; get; }

        public DelegateCommand<object> CopyCommand { set; get; }

        public DelegateCommand<object> SaveCommand { set; get; }

        public string SaveFilePath
        {
            get { return _saveFilePath; }
            set
            {
                _saveFilePath = value;
                notifyPropertyChanged("SaveFilePath");
            }
        }

        #endregion Properties

        #region Methods (11)

        // Private Methods (11) 

        void cancelCommand(object data)
        {
            App.Messenger.NotifyColleagues("AlertSysResult", "Cancelled");
            AlertConfirmBoxModel.CurrentState = "HideAnim"; //animation            
            startHide();
        }

        void confirmCommand(object data)
        {
            App.Messenger.NotifyColleagues("AlertSysResult", "Confirmed");
            AlertConfirmBoxModel.CurrentState = "HideAnim"; //animation            
            startHide();
        }

        void copyCommand(object data)
        {
            var res = getErrorLines();
            if (string.IsNullOrWhiteSpace(res)) return;

            res.ClipboardSetText();
        }

        void doUpdateModel(AlertConfirmBoxModel input)
        {
            if (input != null)
            {
                _localCache.Add(input);
            }

            if (AlertConfirmBoxModel.IsVisible == Visibility.Visible) return;

            if (!_localCache.Any())
                return;

            //show 1st cached item.
            AlertConfirmBoxModel.CurrentState = "FlashAnim"; //animation
            AlertConfirmBoxModel.Errors = _localCache[0].Errors;
            AlertConfirmBoxModel.ErrorTitle = _localCache[0].ErrorTitle;
            AlertConfirmBoxModel.IsVisible = _localCache[0].IsVisible;
            AlertConfirmBoxModel.ShowCancel = _localCache[0].ShowCancel;
            AlertConfirmBoxModel.ShowConfirm = _localCache[0].ShowConfirm;

            _localCache.RemoveAt(0);
        }

        string getErrorLines()
        {
            if (AlertConfirmBoxModel.Errors == null || !AlertConfirmBoxModel.Errors.Any()) return string.Empty;
            return AlertConfirmBoxModel.Errors.Aggregate(string.Empty, (current, line) => current + line + Environment.NewLine);
        }

        void hideIt()
        {
            AlertConfirmBoxModel.Errors = new List<string>();
            AlertConfirmBoxModel.ErrorTitle = string.Empty;
            AlertConfirmBoxModel.IsVisible = Visibility.Collapsed;
        }

        void saveCommand(object data)
        {
            if (string.IsNullOrWhiteSpace(SaveFilePath)) return;
            var res = getErrorLines();
            if (string.IsNullOrWhiteSpace(res)) return;
            File.WriteAllText(SaveFilePath, res);
        }

        private void setupCommands()
        {
            ConfirmCommand = new DelegateCommand<object>(confirmCommand, obj => true);
            CancelCommand = new DelegateCommand<object>(cancelCommand, obj => true);
            CopyCommand = new DelegateCommand<object>(copyCommand, obj => true);
            SaveCommand = new DelegateCommand<object>(saveCommand, obj => true);
        }

        private void setupMessengers()
        {
            App.Messenger.Register<string>("StoryboardCompleted", storyboardCompleted);
            App.Messenger.Register<AlertConfirmBoxModel>("MyMessengerService", doUpdateModel);
        }

        private void startHide()
        {
            AlertConfirmBoxModel.ShowCancel = Visibility.Collapsed;
            AlertConfirmBoxModel.ShowConfirm = Visibility.Collapsed;
        }

        void storyboardCompleted(string state)
        {
            switch (state)
            {
                case "HideAnim":
                    {
                        hideIt();
                        //show next cached item
                        doUpdateModel(null);
                    }
                    break;
                case "FlashAnim":
                    break;
            }
        }

        #endregion Methods



        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void notifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
